import { menu } from "../../decorator";

const { ccclass, property } = cc._decorator;

@ccclass
@menu(__filename)
export default class touchRotate extends cc.Component {
    @property
    _target: cc.Node = null
    @property(cc.Node)
    get target() { return this._target || this.node; }
    set target(value) {
        this._target = value;
    }

    @property({ tooltip: '顺时针' })
    forward = true;

    @property({ tooltip: '逆时针' })
    reverse = true;

    @property({ tooltip: '每一次角度变化不能超过多少<-1代表不限制>' })
    limit = -1;

    // 用来初始化组件或节点的一些属性，当该组件被第一次添加到节点上或用户点击了它的 Reset 菜单时调用。这个回调只会在编辑器下调用。
    resetInEditor() {
        this.target = this.node;
    }

    onLoad() {
        this.node.on("touchstart", this._onTouchStart, this);
        this.node.on("touchmove", this._onTouchMove, this);
    }

    _getDValue(r1, r2) {
        r1 = this._getAngle(r1);
        r2 = this._getAngle(r2);

        if (r2 >= r1) {
            if (r2 - r1 <= 180) {
                return r2 - r1;
            } else {
                return r1 - r2;
            }
        } else {
            if (r1 - r2 >= 180) {
                return r2 - r1 + 360;
            } else {
                return r2 - r1;
            }
        }
    }

    _getAngle(angle) {
        if (angle >= 0 && angle < 360) {
            return angle;
        } else if (angle < 0) {
            return angle % 360 + 360;
        } else {
            return angle % 360;
        }
    }

    _onTouchStart() {
        if (!this.forward && !this.reverse) {
            return false;
        }
    }

    _onTouchMove(event) {
        if (!this.forward && !this.reverse) {
            return;
        }

        const p2 = event.getLocation();
        const p3 = this.node.convertToNodeSpaceAR(p2);

        const p4 = event.getPreviousLocation();
        const p5 = this.node.convertToNodeSpaceAR(p4);

        const radians1 = Math.atan2(p3.y, p3.x);
        const radians2 = Math.atan2(p5.y, p5.x);

        const dValue = this._getDValue(cc.misc.radiansToDegrees(radians2), cc.misc.radiansToDegrees(radians1));

        if (this.limit >= 0 && Math.abs(dValue) > this.limit) {
            return;
        }

        if (dValue == 0) {
            return;
        } else if (dValue > 0) {
            if (!this.reverse) return;
        } else {
            if (!this.forward) return;
        }

        this.target.angle = this._getAngle(this.target.angle + dValue);
    }
}